package com.jgp.third.pay.utils;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.jgp.common.utils.JGPUtil;
import com.jgp.third.pay.model.PaymentConfig;
import com.jgp.third.pay.pojo.AliPaymentParam;
import com.jgp.third.pay.pojo.NormalBatchTransInfo;
import com.jgp.third.pay.pojo.NormalOrderInfo;
import com.jgp.third.pay.pojo.PayQRCode;
import com.jgp.third.pay.utils.ali.AlipaySubmit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2018/10/28
 */
public class PayUtil {
    
    public static Logger logger = LoggerFactory.getLogger(PayUtil.class);
    
    /**
     * 创建支付二维码
     *
     * @param config
     * @param paramMap
     * @return
     */
    public static PayQRCode createQr(PaymentConfig config, NormalOrderInfo orderInfo, Map<String, Object>
            paramMap) {
        PayQRCode qrCode = null;
        switch (config.getMode()) {
            case ALI:
                AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
                model.setSubject(orderInfo.getSubject());
                model.setBody(orderInfo.getBody());
                model.setTotalAmount(orderInfo.getMoney());
                model.setOutTradeNo(orderInfo.getOrderNo());
                model.setTimeoutExpress("60m");//商户门店编号
                model = JGPUtil.merge(model, paramMap);
                qrCode = createAliQr(config, model);
                break;
            case WX:
                break;
            case YL:
                break;
        }
        return qrCode;
    }
    
    
    /**
     * 吊起支付页面
     *
     * @param config
     * @param orderInfo
     * @param extParamMap
     * @param callbackParamsMap
     * @return
     */
    public static String invokePayFormPage(PaymentConfig config, NormalOrderInfo orderInfo, Map<String,
            Object> extParamMap, Map<String, Object> callbackParamsMap) throws IOException {
        AliPaymentParam param = JGPUtil.toBean(config.getConfig(), AliPaymentParam.class);
        AlipayClient alipayClient = createAliPayClient(param);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();//创建API对应的request类
        request.setReturnUrl(config.getDomain() + param.getReturnUrl());
        request.setNotifyUrl(config.getDomain() + param.getNotifyUrl());
        
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setSubject(orderInfo.getSubject());
        model.setBody(orderInfo.getBody());
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        model.setTotalAmount(orderInfo.getMoney());
        model.setOutTradeNo(orderInfo.getOrderNo());
        
        model = JGPUtil.merge(model, extParamMap);
        
        if (Objects.isNull(callbackParamsMap)) {
            callbackParamsMap = new HashMap<>();
        }
        callbackParamsMap.put("configId", orderInfo.getConfigId());
        model.setPassbackParams(URLEncoder.encode(JGPUtil.toJson(callbackParamsMap), "UTF-8"));
        
        request.setBizModel(model);
        AlipayTradePagePayResponse response;
        try {
            response = alipayClient.pageExecute(request);
            if ("10000".equals(response.getCode()) || response.getCode() == null) {
                return response.getBody();
            } else {
                logger.error("支付宝异常代码:{}，【{}】，{}", response.getCode(), response.getMsg(),
                             response.getSubMsg()
                );
            }
        } catch (AlipayApiException e) {
            logger.error("获取支付支付宝支付二维码失败", e);
        }
        return null;
    }
    
    private static PayQRCode createAliQr(PaymentConfig config, AlipayTradePrecreateModel bizContent) {
        AliPaymentParam param = JGPUtil.toBean(config.getConfig(), AliPaymentParam.class);
        AlipayClient alipayClient = createAliPayClient(param);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
        request.setReturnUrl(param.getReturnUrl());
        request.setNotifyUrl(param.getNotifyUrl());
        request.setBizModel(bizContent);
        //request.setBizContent(bizContent);//设置业务参数
        AlipayTradePrecreateResponse response;
        try {
            response = alipayClient.execute(request);
            if ("10000".equals(response.getCode())) {
                return new PayQRCode(response.getOutTradeNo(), response.getQrCode());
            } else {
                logger.error("支付宝异常代码:{}，【{}】，{}", response.getCode(), response.getMsg(),
                             response.getSubMsg()
                );
            }
        } catch (AlipayApiException e) {
            logger.error("获取支付支付宝支付二维码失败", e);
        }
        return null;
    }
    
    private static AlipayClient createAliPayClient(AliPaymentParam param) {
        AlipayClient alipayClient = new DefaultAlipayClient(param.getGatewayUrl(), param.getAppId(),
                                                            param.getMerchantPrivateKey(),
                                                            AlipayConstants.FORMAT_JSON,
                                                            AlipayConstants.CHARSET_UTF8,
                                                            param.getAlipayPublicKey(),
                                                            AlipayConstants.SIGN_TYPE_RSA2
        );
        return alipayClient;
    }
    
    public static String invokeBatchTransFormPage(PaymentConfig config, NormalBatchTransInfo
            batchTransNormalInfo, Map<String, Object> stringObjectMap) {
        AliPaymentParam param = JGPUtil.toBean(config.getConfig(), AliPaymentParam.class);
        //把请求参数打包成数组
        Map<String, String> sParaTemp = new HashMap<>();
        sParaTemp.put("service", "batch_trans_notify");
        sParaTemp.put("partner", param.getPartner());
        sParaTemp.put("_input_charset", "UTF-8");
        sParaTemp.put("notify_url", param.getNotifyUrl());
        sParaTemp.put("email", param.getAccount());
        sParaTemp.put("account_name", param.getAccountName());
        sParaTemp.put("pay_date", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        sParaTemp.put("batch_no", batchTransNormalInfo.getNo());
        sParaTemp.put("batch_fee", batchTransNormalInfo.getMoney()+"");
        sParaTemp.put("batch_num", batchTransNormalInfo.getNum()+"");
        sParaTemp.put("detail_data", batchTransNormalInfo.getDetailsInfo());
        String sHtmlText = AlipaySubmit.buildRequest(param,sParaTemp, "get", "确认");
        return sHtmlText;
    }
}
